/**
* 
* ====================================================================
*
* @author apov <apov@ymail.com>
*/ 
// Socket.h
//

#pragma once

#include "BaseDefine.h"

#ifdef WIN32

#ifndef DEF_VC6
	#include <mstcpip.h>
#endif
	
	const int MSG_NOSIGNAL=		0;
#else
	#include <unistd.h>				
	#include <sys/types.h>			// for accept()
	#include <sys/socket.h>
	#include <sys/time.h>
	#include <arpa/inet.h>			// for inet_xxx()
	#include <netinet/in.h>
	#include <errno.h>				// for errno
	#include <sys/ioctl.h>
	#include <fcntl.h>
	#include <string.h>
	#include <netdb.h>
	typedef struct sockaddr_in SOCKADDR_IN;
	typedef struct in_addr IN_ADDR;
	typedef hostent HOSTENT;
	typedef int	SOCKET;
	static const int INVALID_SOCKET=	-1;
	static const int SOCKET_ERROR=		-1;
	static const int SD_RECEIVE =		SHUT_RD;
	static const int SD_SEND=			SHUT_WR;	
#endif	

typedef struct timeval Timeout;

const int DEF_IP_LEN=			17;

/**
* @class Socket
*
*/	
class Socket{
	enum{
		DEF_MAX_CLOSING_TRY=		5,
	};

public:
	SOCKET accept_socket( char* str_ip_address_out );
	bool connect( const char* ip, int port );
	bool connect( unsigned int ip, int port );	
	bool listen( int port, int backlog );
	bool make_udp_peer( int port );	
	void close_socket();

	unsigned int getIP( char* ip = 0 );
	const char* getStrIP();
	const size_t getPort() const { return port_; }
	int getInputSize();
    int	getOutputSize();
	unsigned int getRemainInput();
	bool isAvailable();

	bool setInputSize( int size );
	bool setOutputSize( int size );
	bool setKeepAlive( int on, unsigned long interval = 0, unsigned long time = 0 );	
	bool setLinger( short onoff, short lingerTime );
	bool setTimeout( int time );
	bool setTcpNoDelay( int flag );
	bool setIOType( bool isBlock );
	
	void setPeer( SOCKET socket, char* str_ip );
	SOCKET getPeer(){ return socket_; }	

	Socket();
	Socket( const Socket& sock );
	virtual ~Socket();

protected:

private:
	int getSockOpt(int level ,int optname, void* optval, int* optlen );

	SOCKET socket_;	

	char ip_[ DEF_IP_LEN ];
	int port_;
};
